<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 构造函数的prototype(原型)上的参数,在被实例化之后如果改变，则所有被实例化出的对象的属性都会被改变
        // 如果被实例化后的对象本身有同样的属性，当被访问时，优先访问自身属性，没有的话会去__proto__中寻找
        // 

        // function Person(name) {
        //     this.name = name;
        //     // this.age = 12
        // }
        // var person = new Person('mamam')
        // var person2 = new Person('guoguo')
        // Person.prototype.age = 18
        //     // console.log(person.age)
        //     // console.log(person2.age)

        // // true，实例化就是把构造函数的prototype赋给person的__proto__的过程
        // // 所以在构造函数的prototype修改后，person的__proto__也被修改    
        // console.log(person.__proto__ === Person.prototype)


        // function Person(name) {
        //     this.name = name;
        // }
        // Person.prototype.age = 18
        // var person = new Person('mamam')
        // var person2 = new Person('guoguo')
        // Person.prototype = {
        //         age: 20
        //     }
        //     // 这里问什么person.__proto__没有被修改：因为这是重新，赋值，不存在对象之间的引用
        // console.log(person.__proto__)
        // console.log(person.age) //18
        // console.log(person2.age) //18



        // function Person(name) {
        //     this.name = name;
        // }
        // Person.prototype.age = 18
        // var person = new Person('mamam')
        //     // 他的原型上除了自己加的属性，好友constructor构造器，和__proto__
        //     // construcotr指向其自身
        //     // __proto__是来自Object的prototype
        // console.log(Person.prototype)


        // 构造函数的constructor和实例对象的__proto__都是可被修改的



        // 在写插件时，一般把需要参数赋值的属性放在构造函数内，方法一般用prototype添加


        // 作业：写一个插件，加减乘除  

        // ;
        // (function() {
        //     function Operation(opt) {
        //         this.num1 = opt.num1;
        //         this.num2 = opt.num2;
        //     }
        //     Operation.prototype.add = function() {
        //         return this.num1 + this.num2
        //     }
        //     Operation.prototype.minus = function() {
        //         return this.num1 - this.num2
        //     }
        //     Operation.prototype.ride = function() {
        //         return this.num1 * this.num2
        //     }
        //     Operation.prototype.divide = function() {
        //         return this.num1 / this.num2
        //     }
        //     window.Operation = Operation;
        // })()
        // var operation = new Operation({
        //     num1: 10,
        //     num2: 5
        // })
        // console.log(operation.add())
        // console.log(operation.minus())
        // console.log(operation.ride())
        // console.log(operation.divide())


        // 对象原型链内置方法不可枚举
        Object.prototype.b = 2;
        const obj = { a: 1 }
        console.log(obj)
        console.log(Object.getOwnPropertyDescriptor(obj.__proto__, 'b'))
        console.log(Object.getOwnPropertyDescriptor(obj.__proto__, 'constructor'))
        Object.defineProperty(obj.__proto__, 'constructor', {
            configurable: true,
            enumerable: true,
            writable: true,
            value: Object.constructor
        })
        console.log(Object.getOwnPropertyDescriptor(obj.__proto__, 'constructor'))
    </script>
</body>

</html>